/////////////////////////////////////////////////////////////////////////////
// GridCtrl.h : header file
//
// MFC Grid Control - main header
//
// Written by Chris Maunder <chris@codeproject.com>
// Copyright (c) 1998-2005. All Rights Reserved.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name and all copyright 
// notices remains intact. 
//
// An email letting me know how you are using it would be nice as well. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability for any damage/loss of business that
// this product may cause.
//
// For use with CGridCtrl v2.20+
//
//////////////////////////////////////////////////////////////////////

// FEATURES BY Mukit, Ataul (2007-11-17):
// 1. Merge Cell 
// 2. Ability to do XL Style Freeze Pane
// 3. The Horizontal Gray Area Removed 
  
// FINDINGS:
// 1. A cell cannot be edited if a tooltip is shown..
// 2. The InplaceEditCtrl is not multiline even if a cell can contain Multiline Text..
// 3. If a cell is too small, the InplaceEditCtrl is almost invisible..

#if !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1456__INCLUDED_)
#define AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1456__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "CellRange.h"
#include "GridCell.h"
#include <afxtempl.h>
#include <vector>


///////////////////////////////////////////////////////////////////////////////////
// Defines - these determine the features (and the final size) of the final code
///////////////////////////////////////////////////////////////////////////////////

//#define GRIDCONTROL_NO_TITLETIPS   // Do not use titletips for cells with large data
//#define GRIDCONTROL_NO_DRAGDROP    // Do not use OLE drag and drop
//#define GRIDCONTROL_NO_CLIPBOARD   // Do not use clipboard routines

#ifdef _WIN32_WCE
#   define GRIDCONTROL_NO_TITLETIPS   // Do not use titletips for cells with large data
#   define GRIDCONTROL_NO_DRAGDROP    // Do not use OLE drag and drop
#   define GRIDCONTROL_NO_CLIPBOARD   // Do not use clipboard routines
#   define GRIDCONTROL_NO_PRINTING    // Do not use printing routines
#   ifdef WCE_NO_PRINTING			  // Older versions of CE had different #def's
#       define _WIN32_WCE_NO_PRINTING
#   endif
#   ifdef WCE_NO_CURSOR
#       define _WIN32_WCE_NO_CURSOR
#   endif
#endif  // _WIN32_WCE

// Use this as the classname when inserting this control as a custom control
// in the MSVC++ dialog editor
#define GRIDCTRL_CLASSNAME    _T("MFCGridCtrl")  // Window class name
#define IDC_INPLACE_CONTROL   8                  // ID of inplace edit controls


///////////////////////////////////////////////////////////////////////////////////
// Conditional includes
///////////////////////////////////////////////////////////////////////////////////

#ifndef GRIDCONTROL_NO_TITLETIPS
#   include "TitleTip.h"
#endif

#ifndef GRIDCONTROL_NO_DRAGDROP
#   include "GridDropTarget.h"
#   undef GRIDCONTROL_NO_CLIPBOARD     // Force clipboard functions on
#endif

#ifndef GRIDCONTROL_NO_CLIPBOARD
#   include <afxole.h>
#endif


///////////////////////////////////////////////////////////////////////////////////
// Helper functions
///////////////////////////////////////////////////////////////////////////////////

// Handy functions
#define IsSHIFTpressed() ( (GetKeyState(VK_SHIFT) & (1 << (sizeof(SHORT)*8-1))) != 0   )
#define IsCTRLpressed()  ( (GetKeyState(VK_CONTROL) & (1 << (sizeof(SHORT)*8-1))) != 0 )

// Backwards compatibility for pre 2.20 grid versions
#define DDX_GridControl(pDX, nIDC, rControl)  DDX_Control(pDX, nIDC, rControl)     


///////////////////////////////////////////////////////////////////////////////////
// Structures
///////////////////////////////////////////////////////////////////////////////////
namespace Printing
{
	// This structure sent to Grid's parent in a WM_NOTIFY message
	typedef struct tagPNT_NM_GRIDVIEW {
		NMHDR hdr;
		int   iRow;
		int   iColumn;
	} PNT_NM_GRIDVIEW;

	// This is sent to the Grid from child in-place edit controls
	typedef struct tagPNT_GV_DISPINFO {
		NMHDR   hdr;
		PNT_GV_ITEM item;
	} PNT_GV_DISPINFO;

	// This is sent to the Grid from child in-place edit controls
	typedef struct tagPNT_GV_CACHEHINT {
		NMHDR      hdr;
		CPntCellRange range;
	} PNT_GV_CACHEHINT;

	// storage typedef for each row in the grid
	typedef CTypedPtrArray<CObArray, Printing::CPntGridCellBase*> PNT_GRID_ROW;

	// For virtual mode callback
	typedef BOOL (CALLBACK* GRIDCALLBACK)(Printing::PNT_GV_DISPINFO *, LPARAM);
}

///////////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////////

// Grid line/scrollbar selection
#define GVL_NONE                0L      // Neither
#define GVL_HORZ                1L      // Horizontal line or scrollbar
#define GVL_VERT                2L      // Vertical line or scrollbar
#define GVL_BOTH                3L      // Both

// Autosizing option
#define GVS_DEFAULT             0
#define GVS_HEADER              1       // Size using column fixed cells data only
#define GVS_DATA                2       // Size using column non-fixed cells data only
#define GVS_BOTH                3       // Size using column fixed and non-fixed

// Cell Searching options
#define GVNI_FOCUSED            0x0001
#define GVNI_SELECTED           0x0002
#define GVNI_DROPHILITED        0x0004
#define GVNI_READONLY           0x0008
#define GVNI_FIXED              0x0010
#define GVNI_MODIFIED           0x0020
// LUC
#define GVNI_FREEZED			0x0040

#define GVNI_ABOVE              LVNI_ABOVE
#define GVNI_BELOW              LVNI_BELOW
#define GVNI_TOLEFT             LVNI_TOLEFT
#define GVNI_TORIGHT            LVNI_TORIGHT
#define GVNI_ALL                (LVNI_BELOW|LVNI_TORIGHT|LVNI_TOLEFT)
#define GVNI_AREA               (LVNI_BELOW|LVNI_TORIGHT)

// Hit test values (not yet implemented)
#define GVHT_DATA               0x0000
#define GVHT_TOPLEFT            0x0001
#define GVHT_COLHDR             0x0002
#define GVHT_ROWHDR             0x0004
#define GVHT_COLSIZER           0x0008
#define GVHT_ROWSIZER           0x0010
#define GVHT_LEFT               0x0020
#define GVHT_RIGHT              0x0040
#define GVHT_ABOVE              0x0080
#define GVHT_BELOW              0x0100

// Messages sent to the grid's parent (More will be added in future)
#define GVN_BEGINDRAG           LVN_BEGINDRAG        // LVN_FIRST-9
#define GVN_BEGINLABELEDIT      LVN_BEGINLABELEDIT   // LVN_FIRST-5
#define GVN_BEGINRDRAG          LVN_BEGINRDRAG
#define GVN_COLUMNCLICK         LVN_COLUMNCLICK
#define GVN_DELETEITEM          LVN_DELETEITEM
#define GVN_ENDLABELEDIT        LVN_ENDLABELEDIT     // LVN_FIRST-6
#define GVN_SELCHANGING         LVN_ITEMCHANGING
#define GVN_SELCHANGED          LVN_ITEMCHANGED
#define GVN_GETDISPINFO         LVN_GETDISPINFO 
#define GVN_ODCACHEHINT         LVN_ODCACHEHINT 

class Printing::CPntGridCtrl;

/////////////////////////////////////////////////////////////////////////////
// CGridCtrl window

typedef bool (*PVIRTUALCOMPARE)(int, int);

namespace Printing
{
	// struct that indicates how the printing is ended
	struct PntPrintEndResult
	{
		bool bEndOfPage; // the printing process ends for reaching the bottom of the page
		bool bEndOfTable;// the printing process ends for reaching the last row of the table
		int pixelOfBottom; // the pixel of the bottom at the end of this round's printing 

		PntPrintEndResult()
		{
			bEndOfPage = false;
			bEndOfTable = false;
			pixelOfBottom = 0;
		}
	};

	class CPntGridCtrl : public CWnd
	{
		DECLARE_DYNCREATE(CPntGridCtrl)
		friend class CPntGridCell;
		friend class CPntGridCellBase;

		// Construction
	public:
		CPntGridCtrl(int nRows = 0, int nCols = 0, int nFixedRows = 0, int nFixedCols = 0, CDC * pDC = NULL);

		BOOL Create(const RECT& rect, CWnd* parent, UINT nID,
			DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE);

		///////////////////////////////////////////////////////////////////////////////////
		// Attributes
		///////////////////////////////////////////////////////////////////////////////////
	public:

		///// LUC ///////////////////////////////////////////////////////////////////////

		//// LUC : MergeCell////////

		INT_PTR MergeCells(CPntCellRange& mergedCellRange);
		void SplitCells(INT_PTR nMergeID);

		BOOL IsMergedCell(int row, int col, CPntCellRange& mergedCellRange);
		BOOL GetMergedCellRect(int row, int col, CRect& rect);
		BOOL GetMergedCellRect(CPntCellRange& mergedCell, CRect& rect);
		BOOL GetTopLeftMergedCell(int& row, int& col, CRect& mergeRect);
		BOOL GetBottomRightMergedCell(int& row, int& col, CRect& mergeRect);
		virtual BOOL IsFocused(CPntGridCellBase& cell, int nRow, int nCol);
		virtual BOOL IsSelected(CPntGridCellBase& cell, int nRow, int nCol);

		BOOL	m_bDrawingMergedCell;
		INT_PTR	m_nCurrentMergeID;

		static CRect rectNull;		
		static CPntCellID cellNull;

		// LUC : Freeze Rows	

		BOOL SetFreezedRowCount(int nFreezedRows)
		{
			BOOL bRet = FALSE;
			if( (nFreezedRows >= 0) && ((nFreezedRows + m_nFixedRows) <= m_nRows) )
			{
				m_nFreezedRows = nFreezedRows;
				ResetScrollBars();
				Refresh();
				bRet = TRUE;
			}

			return bRet;

		}

		BOOL SetFreezedColumnCount(int nFreezedCols)
		{
			BOOL bRet = FALSE;
			if( (nFreezedCols >= 0) && ((nFreezedCols + m_nFixedCols) <= m_nCols) )
			{
				m_nFreezedCols = nFreezedCols;
				ResetScrollBars();
				Refresh();
				bRet = TRUE;
			}

			return bRet;
		}

		// To avoid calling ResetScrollBars twice you can use SetFreezedFrame
		BOOL SetFreezedFrame(int nFreezedRows, int nFreezedCols)
		{
			BOOL bRet = FALSE;
			if( (nFreezedRows >= 0) && ((nFreezedRows + m_nFixedRows) <= m_nRows) )
			{
				m_nFreezedRows = nFreezedRows;			
				bRet = TRUE;
			}
			if( (nFreezedCols >= 0) && ((nFreezedCols + m_nFixedCols) <= m_nCols) )
			{
				m_nFreezedCols = nFreezedCols;
				bRet = TRUE;
			}
			else
			{
				bRet = FALSE;
			}

			ResetScrollBars();

			return bRet;			
		}	

		int  GetFreezedRowCount() const                    { return m_nFreezedRows; }
		int  GetFreezedColumnCount() const                 { return m_nFreezedCols; }	

		void ShowHorzNonGridArea(BOOL bShow)
		{
			m_bShowHorzNonGridArea = bShow;
		}

		BOOL IsShowingHorzNonGridArea()
		{
			return m_bShowHorzNonGridArea;
		}

		///////////////////////////////////////////////////////////////////////////////////////    
		void SetPrintFont(CFont * pFont) {m_pPrinterFont = pFont; }

		////////////////////////////////////////////////////////////////////////////////////////

		int  GetRowCount() const                    { return m_nRows; }
		int  GetColumnCount() const                 { return m_nCols; }
		int  GetFixedRowCount(BOOL bIncludeFreezedRows = FALSE) const
		{ 
			return (bIncludeFreezedRows) ? (m_nFixedRows + m_nFreezedRows) : m_nFixedRows;
		}
		int  GetFixedColumnCount(BOOL bIncludeFreezedCols = FALSE) const            
		{
			return (bIncludeFreezedCols) ? (m_nFixedCols + m_nFreezedCols) : m_nFixedCols; 
		}	

		BOOL SetRowCount(int nRows = 10);
		BOOL SetColumnCount(int nCols = 10);

		BOOL SetFixedRowCount(int nFixedRows = 1);
		BOOL SetFixedColumnCount(int nFixedCols = 1);	

	public:
		int  GetRowHeight(int nRow) const;
		BOOL SetRowHeight(int row, int height);
		int  GetColumnWidth(int nCol) const;
		BOOL SetColumnWidth(int col, int width);

		BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p);
		BOOL GetCellOrigin(const CPntCellID& cell, LPPOINT p);
		BOOL GetCellRect(int nRow, int nCol, LPRECT pRect);
		BOOL GetCellRect(const CPntCellID& cell, LPRECT pRect);

		BOOL GetTextRect(const CPntCellID& cell, LPRECT pRect);
		BOOL GetTextRect(int nRow, int nCol, LPRECT pRect);

		// LUC
		// Change for MergeCell
		CPntCellID GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck = TRUE, CPntCellID& cellOriginal = cellNull);

		// LUC
		//int  GetFixedRowHeight() const;
		//int  GetFixedColumnWidth() const;	    
		int	GetFixedRowHeight(BOOL bIncludeFreezedRows = FALSE) const;
		int GetFixedColumnWidth(BOOL bIncludeFreezedCols = FALSE) const;

		long GetVirtualWidth() const;
		long GetVirtualHeight() const;

		CSize GetTextExtent(int nRow, int nCol, LPCTSTR str);
		// EFW - Get extent of current text in cell
		inline CSize GetCellTextExtent(int nRow, int nCol)  { return GetTextExtent(nRow, nCol, GetItemText(nRow,nCol)); }

		void     SetGridBkColor(COLORREF clr)         { m_crGridBkColour = clr;           }
		COLORREF GetGridBkColor() const               { return m_crGridBkColour;          }
		void     SetGridLineColor(COLORREF clr)       { m_crGridLineColour = clr;         }
		COLORREF GetGridLineColor() const             { return m_crGridLineColour;        }

		void	 SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) { m_crTTipBackClr = clr;  }
		COLORREF GetTitleTipBackClr()				            { return m_crTTipBackClr; }
		void	 SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) { m_crTTipTextClr = clr;  }
		COLORREF GetTitleTipTextClr()				            { return m_crTTipTextClr; }

		// ***************************************************************************** //
		// These have been deprecated. Use GetDefaultCell and then set the colors
		void     SetTextColor(COLORREF clr)      { m_pCellDefault->SetTextClr(clr);        }
		COLORREF GetTextColor()                  { return m_pCellDefault->GetTextClr();    }
		void     SetTextBkColor(COLORREF clr)    { m_pCellDefault->SetBackClr(clr);        }
		COLORREF GetTextBkColor()                { return m_pCellDefault->GetBackClr();    }
		void     SetFixedTextColor(COLORREF clr) { m_cellFixedRowDef.SetTextClr(clr); 
		m_cellFixedColDef.SetTextClr(clr); 
		m_cellFixedRowColDef.SetTextClr(clr); }
		COLORREF GetFixedTextColor() const       { return m_cellFixedRowDef.GetTextClr(); }
		void     SetFixedBkColor(COLORREF clr)   { m_cellFixedRowDef.SetBackClr(clr); 
		m_cellFixedColDef.SetBackClr(clr); 
		m_cellFixedRowColDef.SetBackClr(clr); }
		COLORREF GetFixedBkColor() const         { return m_cellFixedRowDef.GetBackClr(); }
		void     SetGridColor(COLORREF clr)      { SetGridLineColor(clr);                }
		COLORREF GetGridColor()                  { return GetGridLineColor();            }
		void     SetBkColor(COLORREF clr)        { SetGridBkColor(clr);                  }
		COLORREF GetBkColor()                    { return GetGridBkColor();              }

		void     SetDefCellMargin( int nMargin)  { m_pCellDefault->SetMargin(nMargin); 
		m_cellFixedRowDef.SetMargin(nMargin); 
		m_cellFixedColDef.SetMargin(nMargin); 
		m_cellFixedRowColDef.SetMargin(nMargin); }
		int      GetDefCellMargin() const        { return m_pCellDefault->GetMargin();     }

		int      GetDefCellHeight() const        { return m_pCellDefault->GetHeight();     }
		void     SetDefCellHeight(int nHeight)   { m_pCellDefault->SetHeight(nHeight); 
		m_cellFixedRowDef.SetHeight(nHeight); 
		m_cellFixedColDef.SetHeight(nHeight); 
		m_cellFixedRowColDef.SetHeight(nHeight); }
		int      GetDefCellWidth() const         { return m_pCellDefault->GetWidth();     }
		void     SetDefCellWidth(int nWidth)     { m_pCellDefault->SetWidth(nWidth); 
		m_cellFixedRowDef.SetWidth(nWidth); 
		m_cellFixedColDef.SetWidth(nWidth); 
		m_cellFixedRowColDef.SetWidth(nWidth); }

		// ***************************************************************************** //

		int GetSelectedCount() const                  { return (int)m_SelectedCellMap.GetCount(); }

		CPntCellID SetFocusCell(CPntCellID cell);
		CPntCellID SetFocusCell(int nRow, int nCol);
		CPntCellID GetFocusCell() const                  { return m_idCurrentCell;           }


		void SetVirtualMode(BOOL bVirtual);
		BOOL GetVirtualMode() const                   { return m_bVirtualMode;            }
		void SetCallbackFunc(GRIDCALLBACK pCallback, 
			LPARAM lParam)           { m_pfnCallback = pCallback; m_lParam = lParam; }
		GRIDCALLBACK GetCallbackFunc()                { return m_pfnCallback;             }


		void SetImageList(CImageList* pList)          { m_pImageList = pList;             }
		CImageList* GetImageList() const              { return m_pImageList;              }

		void SetGridLines(int nWhichLines = GVL_BOTH);
		int  GetGridLines() const                     { return m_nGridLines;              }
		void SetEditable(BOOL bEditable = TRUE)       { m_bEditable = bEditable;          }
		BOOL IsEditable() const                       { return m_bEditable;               }
		void SetListMode(BOOL bEnableListMode = TRUE);
		BOOL GetListMode() const                      { return m_bListMode;               }
		void SetSingleRowSelection(BOOL bSing = TRUE) { m_bSingleRowSelection = bSing;    }
		BOOL GetSingleRowSelection()                  { return m_bSingleRowSelection & m_bListMode; }
		void SetSingleColSelection(BOOL bSing = TRUE) { m_bSingleColSelection = bSing;    }
		BOOL GetSingleColSelection()                  { return m_bSingleColSelection;     }
		void EnableSelection(BOOL bEnable = TRUE)     { ResetSelectedRange(); m_bEnableSelection = bEnable; ResetSelectedRange(); }
		BOOL IsSelectable() const                     { return m_bEnableSelection;        }
		void SetFixedColumnSelection(BOOL bSelect)    { m_bFixedColumnSelection = bSelect;}
		BOOL GetFixedColumnSelection()                { return m_bFixedColumnSelection;   }
		void SetFixedRowSelection(BOOL bSelect)       { m_bFixedRowSelection = bSelect;   }
		BOOL GetFixedRowSelection()                   { return m_bFixedRowSelection;      }
		void EnableDragAndDrop(BOOL bAllow = TRUE)    { m_bAllowDragAndDrop = bAllow;     }
		BOOL GetDragAndDrop() const                   { return m_bAllowDragAndDrop;       }
		void SetRowResize(BOOL bResize = TRUE)        { m_bAllowRowResize = bResize;      }
		BOOL GetRowResize() const                     { return m_bAllowRowResize;         }
		void SetColumnResize(BOOL bResize = TRUE)     { m_bAllowColumnResize = bResize;   }
		BOOL GetColumnResize() const                  { return m_bAllowColumnResize;      }
		void SetHeaderSort(BOOL bSortOnClick = TRUE)  { m_bSortOnClick = bSortOnClick;    }
		BOOL GetHeaderSort() const                    { return m_bSortOnClick;            }
		void SetHandleTabKey(BOOL bHandleTab = TRUE)  { m_bHandleTabKey = bHandleTab;     }
		BOOL GetHandleTabKey() const                  { return m_bHandleTabKey;           }
		void SetDoubleBuffering(BOOL bBuffer = TRUE)  { m_bDoubleBuffer = bBuffer;        }
		BOOL GetDoubleBuffering() const               { return m_bDoubleBuffer;           }
		void EnableTitleTips(BOOL bEnable = TRUE)     { m_bTitleTips = bEnable;           }
		BOOL GetTitleTips()                           { return m_bTitleTips;              }
		void SetSortColumn(int nCol);
		int  GetSortColumn() const                    { return m_nSortColumn;             }
		void SetSortAscending(BOOL bAscending)        { m_bAscending = bAscending;        }
		BOOL GetSortAscending() const                 { return m_bAscending;              }
		void SetTrackFocusCell(BOOL bTrack)           { m_bTrackFocusCell = bTrack;       }
		BOOL GetTrackFocusCell()                      { return m_bTrackFocusCell;         }
		void SetFrameFocusCell(BOOL bFrame)           { m_bFrameFocus = bFrame;           }
		BOOL GetFrameFocusCell()                      { return m_bFrameFocus;             }
		void SetAutoSizeStyle(int nStyle = GVS_BOTH)  { m_nAutoSizeColumnStyle = nStyle;  }
		int  GetAutoSizeStyle()                       { return m_nAutoSizeColumnStyle; }

		void EnableHiddenColUnhide(BOOL bEnable = TRUE){ m_bHiddenColUnhide = bEnable;    }
		BOOL GetHiddenColUnhide()                     { return m_bHiddenColUnhide;        }
		void EnableHiddenRowUnhide(BOOL bEnable = TRUE){ m_bHiddenRowUnhide = bEnable;    }
		BOOL GetHiddenRowUnhide()                     { return m_bHiddenRowUnhide;        }

		void EnableColumnHide(BOOL bEnable = TRUE)    { m_bAllowColHide = bEnable;        }
		BOOL GetColumnHide()                          { return m_bAllowColHide;           }
		void EnableRowHide(BOOL bEnable = TRUE)       { m_bAllowRowHide = bEnable;        }
		BOOL GetRowHide()                             { return m_bAllowRowHide;           }

		///////////////////////////////////////////////////////////////////////////////////
		// default Grid cells. Use these for setting default values such as colors and fonts
		///////////////////////////////////////////////////////////////////////////////////
	public:
		CPntGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const;

		///////////////////////////////////////////////////////////////////////////////////
		// Grid cell Attributes
		///////////////////////////////////////////////////////////////////////////////////
	public:
		CPntGridCellBase* GetCell(int nRow, int nCol) const;   // Get the actual cell!

		void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1);
		BOOL GetModified(int nRow = -1, int nCol = -1);
		BOOL IsCellFixed(int nRow, int nCol);

		BOOL   SetItem(const PNT_GV_ITEM* pItem);
		BOOL   GetItem(PNT_GV_ITEM* pItem);
		BOOL   SetItemText(int nRow, int nCol, LPCTSTR str);
		// The following was virtual. If you want to override, use 
		//  CGridCellBase-derived class's GetText() to accomplish same thing
		CString GetItemText(int nRow, int nCol) const;

		// EFW - 06/13/99 - Added to support printf-style formatting codes.
		// Also supports use with a string resource ID
#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 210)
		BOOL   SetItemTextFmt(int nRow, int nCol, LPCTSTR szFmt, ...);
		BOOL   SetItemTextFmtID(int nRow, int nCol, UINT nID, ...);
#endif

		BOOL   SetItemData(int nRow, int nCol, LPARAM lParam);
		LPARAM GetItemData(int nRow, int nCol) const;
		BOOL   SetItemImage(int nRow, int nCol, int iImage);
		int    GetItemImage(int nRow, int nCol) const;
		BOOL   SetItemState(int nRow, int nCol, UINT state);
		UINT   GetItemState(int nRow, int nCol) const;
		BOOL   SetCellFormat(int nRow, int nCol, UINT nFormat);
		UINT   GetItemFormat(int nRow, int nCol) const;
		BOOL   SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
		COLORREF GetItemBkColour(int nRow, int nCol) const;
		BOOL   SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
		COLORREF GetItemFgColour(int nRow, int nCol) const;
		BOOL SetItemFont(int nRow, int nCol, const LOGFONT* lf);
		const LOGFONT* GetItemFont(int nRow, int nCol);

		BOOL IsItemEditing(int nRow, int nCol);

		BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass);
		BOOL SetDefaultCellType( CRuntimeClass* pRuntimeClass);

		///////////////////////////////////////////////////////////////////////////////////
		// Operations
		///////////////////////////////////////////////////////////////////////////////////
	public:
		int  InsertColumn(LPCTSTR strHeading, UINT nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE,
			int nColumn = -1);
		int  InsertRow(LPCTSTR strHeading, int nRow = -1);
		BOOL DeleteColumn(int nColumn);
		BOOL DeleteRow(int nRow);
		BOOL DeleteNonFixedRows();
		BOOL DeleteAllItems();

		void ClearCells(CPntCellRange Selection);

		BOOL AutoSizeRow(int nRow, BOOL bResetScroll = TRUE);
		BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL bResetScroll = TRUE);
		void AutoSizeRows();
		void AutoSizeColumns(UINT nAutoSizeStyle = GVS_DEFAULT);
		void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT);
		void ExpandColumnsToFit(BOOL bExpandFixed = TRUE);
		void ExpandLastColumn();
		void ExpandRowsToFit(BOOL bExpandFixed = TRUE);
		void ExpandToFit(BOOL bExpandFixed = TRUE);

		void Refresh();
		void AutoFill();   // Fill grid with blank cells

		void EnsureVisible(CPntCellID &cell)       { EnsureVisible(cell.row, cell.col); }
		void EnsureVisible(int nRow, int nCol);
		BOOL IsCellVisible(int nRow, int nCol);
		BOOL IsCellVisible(CPntCellID cell);
		BOOL IsCellEditable(int nRow, int nCol) const;
		BOOL IsCellEditable(CPntCellID &cell) const;
		BOOL IsCellSelected(int nRow, int nCol) const;
		BOOL IsCellSelected(CPntCellID &cell) const;

		// SetRedraw stops/starts redraws on things like changing the # rows/columns
		// and autosizing, but not for user-intervention such as resizes
		void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE);
		BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL);
		BOOL RedrawCell(const CPntCellID& cell, CDC* pDC = NULL);
		BOOL RedrawRow(int row);
		BOOL RedrawColumn(int col);

#ifndef _WIN32_WCE
		BOOL Save(LPCTSTR filename, TCHAR chSeparator = _T(','));
		BOOL Load(LPCTSTR filename, TCHAR chSeparator = _T(','));
#endif

		///////////////////////////////////////////////////////////////////////////////////
		// Cell Ranges
		///////////////////////////////////////////////////////////////////////////////////
	public:
		CPntCellRange GetCellRange() const;
		CPntCellRange GetSelectedCellRange() const;
		void SetSelectedRange(const CPntCellRange& Range, BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
		void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol,
			BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
		BOOL IsValid(int nRow, int nCol) const;
		BOOL IsValid(const CPntCellID& cell) const;
		BOOL IsValid(const CPntCellRange& range) const;

		///////////////////////////////////////////////////////////////////////////////////
		// Clipboard, drag and drop, and cut n' paste operations
		///////////////////////////////////////////////////////////////////////////////////
#ifndef GRIDCONTROL_NO_CLIPBOARD
		virtual void CutSelectedText();
		virtual COleDataSource* CopyTextFromGrid();
		virtual BOOL PasteTextToGrid(CPntCellID cell, COleDataObject* pDataObject, BOOL bSelectPastedCells=TRUE);
#endif

#ifndef GRIDCONTROL_NO_DRAGDROP
	public:
		virtual void OnBeginDrag();
		virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
		virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
		virtual void OnDragLeave();
		virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
#endif

#ifndef GRIDCONTROL_NO_CLIPBOARD
		virtual void OnEditCut();
		virtual void OnEditCopy();
		virtual void OnEditPaste();
#endif
		virtual void OnEditSelectAll();

		///////////////////////////////////////////////////////////////////////////////////
		// Misc.
		///////////////////////////////////////////////////////////////////////////////////
	public:
		CPntCellID GetNextItem(CPntCellID& cell, int nFlags) const;

		BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0);
		BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0);
		BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data = 0);

		void SetCompareFunction(PFNLVCOMPARE pfnCompare);

		// in-built sort functions
		static int CALLBACK pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
		static int CALLBACK pfnCellNumericCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);

		///////////////////////////////////////////////////////////////////////////////////
		// Printing
		///////////////////////////////////////////////////////////////////////////////////
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
	public:
		// EFW - New printing support functions
		void SetShadedPrintOut(BOOL bEnable = TRUE)     {   m_bShadedPrintOut = bEnable;    }
		BOOL GetShadedPrintOut(void)                    {   return m_bShadedPrintOut;       }

		// Use -1 to have it keep the existing value
		void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight,
			int nLeftMargin, int nRightMargin, int nTopMargin,
			int nBottomMargin, int nGap);

		void GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight,
			int &nLeftMargin, int &nRightMargin, int &nTopMargin,
			int &nBottomMargin, int &nGap);

		///////////////////////////////////////////////////////////////////////////////////
		// Printing overrides for derived classes
		///////////////////////////////////////////////////////////////////////////////////
	public:
		virtual int OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo, CRect clientRect);
		virtual void OnPrint(CDC *pDC, int currentPageNum, CRect clientRect, PntPrintEndResult* printedEndReslt = NULL);
		virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo);

#endif // #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)

		// Implementation
	public:
		virtual ~CPntGridCtrl();

	protected:
		BOOL RegisterWindowClass();
		BOOL Initialise();
		void SetupDefaultCells();

		LRESULT SendMessageToParent(int nRow, int nCol, int nMessage) const;
		LRESULT SendDisplayRequestToParent(PNT_GV_DISPINFO* pDisplayInfo) const;
		LRESULT SendCacheHintToParent(const CPntCellRange& range) const;

		BOOL InvalidateCellRect(const int row, const int col);
		BOOL InvalidateCellRect(const CPntCellID& cell);
		BOOL InvalidateCellRect(const CPntCellRange& cellRange);
		void EraseBkgnd(CDC* pDC);

		BOOL GetCellRangeRect(const CPntCellRange& cellRange, LPRECT lpRect);

		BOOL SetCell(int nRow, int nCol, CPntGridCellBase* pCell);

		int  SetMouseMode(int nMode) { int nOldMode = m_MouseMode; m_MouseMode = nMode; return nOldMode; }
		int  GetMouseMode() const    { return m_MouseMode; }

		BOOL MouseOverRowResizeArea(CPoint& point);
		BOOL MouseOverColumnResizeArea(CPoint& point);

		CPntCellID GetTopleftNonFixedCell(BOOL bForceRecalculation = FALSE);
		CPntCellRange GetUnobstructedNonFixedCellRange(BOOL bForceRecalculation = FALSE);
		// LUC
		CPntCellRange GetVisibleNonFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE);
		CPntCellRange GetVisibleFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE);

		BOOL IsVisibleVScroll() { return ( (m_nBarState & GVL_VERT) > 0); } 
		BOOL IsVisibleHScroll() { return ( (m_nBarState & GVL_HORZ) > 0); }
		void ResetSelectedRange();
		void ResetScrollBars();
		void EnableScrollBars(int nBar, BOOL bEnable = TRUE);
		int  GetScrollPos32(int nBar, BOOL bGetTrackPos = FALSE);
		BOOL SetScrollPos32(int nBar, int nPos, BOOL bRedraw = TRUE);

		BOOL SortTextItems(int nCol, BOOL bAscending, int low, int high);
		BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data,
			int low, int high);

		CPoint GetPointClicked(int nRow, int nCol, const CPoint& point);

		void ValidateAndModifyCellContents(int nRow, int nCol, LPCTSTR strText);

		// Overrrides
		// ClassWizard generated virtual function overrides
		//{{AFX_VIRTUAL(CGridCtrl)
	protected:
		virtual void PreSubclassWindow();
		//}}AFX_VIRTUAL

	protected:
#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
		// Printing
		virtual void PrintFixedRowCells(int nStartColumn, int nStopColumn, int& row, CRect& rect,
			CDC *pDC, BOOL& bFirst);
		virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);
		virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);
		virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);
		virtual void PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/);
#endif

#ifndef GRIDCONTROL_NO_DRAGDROP
		// Drag n' drop
		virtual CImageList* CreateDragImage(CPoint *pHotSpot);    // no longer necessary
#endif

		// Mouse Clicks
		virtual void  OnFixedColumnClick(CPntCellID& cell);
		virtual void  OnFixedRowClick(CPntCellID& cell);

		// Editing
		virtual void  OnEditCell(int nRow, int nCol, CPoint point, UINT nChar);
		virtual void  OnEndEditCell(int nRow, int nCol, CString str);
		virtual BOOL  ValidateEdit(int nRow, int nCol, LPCTSTR str);
		virtual void  EndEditing();

		// Drawing
		virtual void  OnDraw(CDC* pDC);

		// CGridCellBase Creation and Cleanup
		virtual CPntGridCellBase* CreateCell(int nRow, int nCol);
		virtual void DestroyCell(int nRow, int nCol);

		// Attributes
	protected:
		// General attributes
		COLORREF    m_crFixedTextColour, m_crFixedBkColour;
		COLORREF    m_crGridBkColour, m_crGridLineColour;
		COLORREF    m_crWindowText, m_crWindowColour, m_cr3DFace,     // System colours
			m_crShadow;
		COLORREF    m_crTTipBackClr, m_crTTipTextClr;                 // Titletip colours - FNA

		BOOL        m_bVirtualMode;
		LPARAM      m_lParam;                                           // lParam for callback
		GRIDCALLBACK m_pfnCallback;                                     // The callback function

		int         m_nGridLines;
		BOOL        m_bEditable;
		BOOL        m_bModified;
		BOOL        m_bAllowDragAndDrop;
		BOOL        m_bListMode;
		BOOL        m_bSingleRowSelection;
		BOOL        m_bSingleColSelection;
		BOOL        m_bAllowDraw;
		BOOL        m_bEnableSelection;
		BOOL        m_bFixedRowSelection, m_bFixedColumnSelection;
		BOOL        m_bSortOnClick;
		BOOL        m_bHandleTabKey;
		BOOL        m_bDoubleBuffer;
		BOOL        m_bTitleTips;
		int         m_nBarState;
		BOOL        m_bWysiwygPrinting;
		BOOL        m_bHiddenColUnhide, m_bHiddenRowUnhide;
		BOOL        m_bAllowColHide, m_bAllowRowHide;
		BOOL        m_bAutoSizeSkipColHdr;
		BOOL        m_bTrackFocusCell;
		BOOL        m_bFrameFocus;
		UINT        m_nAutoSizeColumnStyle;

		// Cell size details
		int         m_nRows, m_nFixedRows, m_nCols, m_nFixedCols;
		// LUC
		int			m_nFreezedRows, m_nFreezedCols;
		BOOL m_bExcludeFreezedRowsFromSelection;
		BOOL m_bExcludeFreezedColsFromSelection;

		// LUC
		CArray<CPntCellRange, CPntCellRange&> m_arMergedCells;
		// LUC
		BOOL m_bShowHorzNonGridArea;

		CUIntArray  m_arRowHeights, m_arColWidths;
		int         m_nVScrollMax, m_nHScrollMax;

		// Fonts and images
		CRuntimeClass*   m_pRtcDefault; // determines kind of Grid Cell created by default
		CPntGridDefaultCell *m_pCellDefault;  // "default" cell. Contains default colours, font etc.
		CPntGridDefaultCell m_cellFixedColDef, m_cellFixedRowDef, m_cellFixedRowColDef;
		CFont*       m_pPrinterFont;  // for the printer
		CImageList* m_pImageList;

		// Cell data
		CTypedPtrArray<CObArray, PNT_GRID_ROW*> m_RowData;

		// Mouse operations such as cell selection
		int         m_MouseMode;
		BOOL        m_bLMouseButtonDown, m_bRMouseButtonDown;
		CPoint      m_LeftClickDownPoint, m_LastMousePoint;
		CPntCellID     m_LeftClickDownCell, m_SelectionStartCell;
		CPntCellID     m_idCurrentCell, m_idTopLeftCell;
		INT_PTR     m_nTimerID;
		int         m_nTimerInterval;
		int         m_nResizeCaptureRange;
		BOOL        m_bAllowRowResize, m_bAllowColumnResize;
		int         m_nRowsPerWheelNotch;
		CMap<DWORD,DWORD, CPntCellID, CPntCellID&> m_SelectedCellMap, m_PrevSelectedCellMap;

#ifndef GRIDCONTROL_NO_TITLETIPS
		CPntTitleTip   m_TitleTip;             // Title tips for cells
#endif

		// Drag and drop
		CPntCellID     m_LastDragOverCell;
#ifndef GRIDCONTROL_NO_DRAGDROP
		CPntGridDropTarget m_DropTarget;       // OLE Drop target for the grid
#endif

		// Printing information
		CSize       m_CharSize;
		int         m_nPageHeight;
		CSize       m_LogicalPageSize,      // Page size in gridctrl units.
			m_PaperSize;            // Page size in device units.
		// additional properties to support Wysiwyg printing
		int         m_nPageWidth;
		int         m_nPrintColumn;
		int         m_nCurrPrintRow;
		int         m_nNumPages;
		int         m_nPageMultiplier;

		// sorting
		int          m_bAscending;
		int          m_nSortColumn;
		PFNLVCOMPARE m_pfnCompare;

		// EFW - Added to support shaded/unshaded printout.  If true, colored
		// cells will print as-is.  If false, all text prints as black on white.
		BOOL        m_bShadedPrintOut;

		// EFW - Added support for user-definable margins.  Top and bottom are in 
		// lines.  Left, right, and gap are in characters (avg width is used).
		int         m_nHeaderHeight, m_nFooterHeight, m_nLeftMargin,
			m_nRightMargin, m_nTopMargin, m_nBottomMargin, m_nGap;

		bool m_bNeedDrawHeading;
		CDC * m_pDC;
	public:
		void SetNeedDrawHeading(bool bNeedDraw) {m_bNeedDrawHeading = bNeedDraw; }

	protected:
		void SelectAllCells();
		void SelectColumns(CPntCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
		void SelectRows(CPntCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
		void SelectCells(CPntCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
		void OnSelecting(const CPntCellID& currentCell);

		// Generated message map functions
		//{{AFX_MSG(CGridCtrl)
		afx_msg void OnPaint();
		afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
		afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
		afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnMouseMove(UINT nFlags, CPoint point);
		afx_msg void OnTimer(UINT nIDEvent);
		afx_msg UINT OnGetDlgCode();
		afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
		afx_msg BOOL OnEraseBkgnd(CDC* pDC);
		afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnUpdateEditSelectAll(CCmdUI* pCmdUI);
		//}}AFX_MSG
#ifndef _WIN32_WCE_NO_CURSOR
		afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
#endif
#ifndef _WIN32_WCE
		afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
		afx_msg void OnRButtonUp(UINT nFlags, CPoint point);    // EFW - Added
		afx_msg void OnSysColorChange();
#endif
#ifndef _WIN32_WCE_NO_CURSOR
		afx_msg void OnCaptureChanged(CWnd *pWnd);
#endif
#ifndef GRIDCONTROL_NO_CLIPBOARD
		afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
		afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
		afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
#endif
#if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
		afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
#endif
#if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
		afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
#endif
		afx_msg LRESULT OnSetFont(WPARAM hFont, LPARAM lParam);
		afx_msg LRESULT OnGetFont(WPARAM hFont, LPARAM lParam);
		afx_msg LRESULT OnImeChar(WPARAM wCharCode, LPARAM lParam);
		afx_msg void OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult);
		DECLARE_MESSAGE_MAP()

		enum eMouseModes { MOUSE_NOTHING, MOUSE_SELECT_ALL, MOUSE_SELECT_COL, MOUSE_SELECT_ROW,
			MOUSE_SELECT_CELLS, MOUSE_SCROLLING_CELLS,
			MOUSE_OVER_ROW_DIVIDE, MOUSE_SIZING_ROW,
			MOUSE_OVER_COL_DIVIDE, MOUSE_SIZING_COL,
			MOUSE_PREPARE_EDIT,
#ifndef GRIDCONTROL_NO_DRAGDROP
			MOUSE_PREPARE_DRAG, MOUSE_DRAGGING
#endif
		};
		//      for sort in virtual mode, and column order, save and load layer
	public:
		typedef std::vector<int> intlist;
		void Reorder(int From, int To);
		void SetVirtualCompare(PVIRTUALCOMPARE VirtualCompare) { m_pfnVirtualCompare = VirtualCompare;}
		int m_CurCol;
		void AllowReorderColumn(bool b=true) { m_AllowReorderColumn = b;}
		void EnableDragRowMode(bool b=true) { m_bDragRowMode = b; if(b) EnableDragAndDrop(); } // to change row order
		int GetLayer(int** pLayer); //  gives back the number of ints of the area (do not forget to delete *pLayer)
		void SetLayer(int* pLayer); // coming from a previous GetLayer (ignored if not same number of column, or the same revision number)
		void ForceQuitFocusOnTab(bool b=true) { m_QuitFocusOnTab = b;} // use only if GetParent() is a CDialog
		void AllowSelectRowInFixedCol(bool b=true) { m_AllowSelectRowInFixedCol = b;} // 
		//    allow acces?
		intlist m_arRowOrder, m_arColOrder;
		static CPntGridCtrl* m_This;
	protected:
		virtual void AddSubVirtualRow(int Num, int Nb);
		bool m_bDragRowMode;
		int m_CurRow;
	private:
		void ResetVirtualOrder();
		PVIRTUALCOMPARE m_pfnVirtualCompare;
		static bool NotVirtualCompare(int c1, int c2);
		bool m_InDestructor;
		bool m_AllowReorderColumn;
		bool m_QuitFocusOnTab;
		bool m_AllowSelectRowInFixedCol;

	};

	// Returns the default cell implementation for the given grid region
	inline CPntGridCellBase* CPntGridCtrl::GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const
	{ 
		if (bFixedRow && bFixedCol) return (CPntGridCellBase*) &m_cellFixedRowColDef;
		if (bFixedRow)              return (CPntGridCellBase*) &m_cellFixedRowDef;
		if (bFixedCol)              return (CPntGridCellBase*) &m_cellFixedColDef;
		return (CPntGridCellBase*) m_pCellDefault;
	}

	inline CPntGridCellBase* CPntGridCtrl::GetCell(int nRow, int nCol) const
	{
		if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols) 
			return NULL;

		if (GetVirtualMode())
		{
			CPntGridCellBase* pCell = GetDefaultCell(nRow < m_nFixedRows, nCol < m_nFixedCols);
			static PNT_GV_DISPINFO gvdi;
			gvdi.item.row     = nRow;
			gvdi.item.col     = nCol;
			gvdi.item.mask    = 0xFFFFFFFF;
			gvdi.item.nState  = 0;
			gvdi.item.nFormat = pCell->GetFormat();
			gvdi.item.iImage  = pCell->GetImage();
			gvdi.item.crBkClr = pCell->GetBackClr();
			gvdi.item.crFgClr = pCell->GetTextClr();
			gvdi.item.lParam  = pCell->GetData();
			memcpy(&gvdi.item.lfFont, pCell->GetFont(), sizeof(LOGFONT));
			gvdi.item.nMargin = pCell->GetMargin();
			gvdi.item.strText.Empty();

			// Fix the state bits
			if (IsCellSelected(nRow, nCol))   gvdi.item.nState |= GVIS_SELECTED;
			if (nRow < GetFixedRowCount())    gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDROW);
			if (nCol < GetFixedColumnCount()) gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDCOL);
			if (GetFocusCell() == CPntCellID(nRow, nCol)) gvdi.item.nState |= GVIS_FOCUSED;
			if(!m_InDestructor)
			{
				gvdi.item.row = m_arRowOrder[nRow];
				gvdi.item.col = m_arColOrder[nCol];

				if (m_pfnCallback)
					m_pfnCallback(&gvdi, m_lParam);
				else
					SendDisplayRequestToParent(&gvdi);
				gvdi.item.row = nRow;        
				gvdi.item.col = nCol;
			}
			static CPntGridCell cell;
			cell.SetState(gvdi.item.nState);
			cell.SetFormat(gvdi.item.nFormat);
			cell.SetImage(gvdi.item.iImage);
			cell.SetBackClr(gvdi.item.crBkClr);
			cell.SetTextClr(gvdi.item.crFgClr);
			cell.SetData(gvdi.item.lParam);
			cell.SetFont(&(gvdi.item.lfFont));
			cell.SetMargin(gvdi.item.nMargin);
			cell.SetText(gvdi.item.strText);
			cell.SetGrid((CPntGridCtrl*)this);

			return (CPntGridCellBase*) &cell;
		}

		PNT_GRID_ROW* pRow = m_RowData[nRow];
		if (!pRow) return NULL;
		return pRow->GetAt(m_arColOrder[nCol]);
	}

	inline BOOL CPntGridCtrl::SetCell(int nRow, int nCol, CPntGridCellBase* pCell)
	{
		if (GetVirtualMode())
			return FALSE;

		if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols) 
			return FALSE;

		PNT_GRID_ROW* pRow = m_RowData[nRow];
		if (!pRow) return FALSE;

		pCell->SetCoords( nRow, nCol); 
		pRow->SetAt(nCol, pCell);

		return TRUE;
	}

	/////////////////////////////////////////////////////////////////////////////

	//{{AFX_INSERT_LOCATION}}
	// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
}

#endif // !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1456__INCLUDED_)
